//-----------------------------------------------------------------------------
// Copyright (c) 2006-2008 dhpoware. All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
#pragma once
#include "precompiled.h"

class Camera_Alt
{
public:
	Camera_Alt();
	~Camera_Alt();

	void lookAt(const glm::vec3 &target);
	void lookAt(const glm::vec3 &eye, const glm::vec3 &target, const glm::vec3 &up);
	void move(float dx, float dy, float dz);
	void move(const glm::vec3 &direction, const glm::vec3 &amount);
	void perspective(float fovx, float aspect, float znear, float zfar);
	void rotate(float headingDegrees, float pitchDegrees, float rollDegrees);
	void updatePosition(const glm::vec3 &direction, float elapsedTimeSec);

	void Update( GLdouble time );

	// Getter methods.

	const glm::vec3 &getAcceleration() const;
	const glm::vec3 &getCurrentVelocity() const;
	const glm::vec3 getPosition() const;
	const glm::mat4 &getProjectionMatrix() const;
	const glm::vec3 &getVelocity() const;
	const glm::vec3 &getViewDirection() const;
	const glm::mat4 &getViewMatrix() const;
	const glm::vec3 &getXAxis() const;
	const glm::vec3 &getYAxis() const;
	const glm::vec3 &getZAxis() const;
	const float &getFov() const;
	const float &getZNear() const;
	const float &getZFar() const;
	const glm::vec3 getEuler() const;

	// How far is a position from the camera?
	const float &getDistanceFromCamera( glm::vec3 pos ) const;

	// More get.......................................
	glm::mat4* getCameraMatrix( );
	glm::vec2 get_mouseScreenDistanceFromCenter();

	// Setter methods.

	void setAcceleration(float x, float y, float z);
	void setAcceleration(const glm::vec3 &acceleration);
	void setCurrentVelocity(float x, float y, float z);
	void setCurrentVelocity(const glm::vec3 &currentVelocity);
	void setPosition(float x, float y, float z);
	void setPosition(const glm::vec3 &position);
	void setVelocity(float x, float y, float z);
	void setVelocity(const glm::vec3 &velocity);

	glm::mat4 m_rotMatrix;
private:
	void rotateFirstPerson(float headingDegrees, float pitchDegrees);
	void updateVelocity(const glm::vec3 &direction, float elapsedTimeSec);
	void updateViewMatrix(bool orthogonalizeAxes);

	static const float DEFAULT_FOVX;
	static const float DEFAULT_ZFAR;
	static const float DEFAULT_ZNEAR;
	static const glm::vec3 WORLD_XAXIS;
	static const glm::vec3 WORLD_YAXIS;
	static const glm::vec3 WORLD_ZAXIS;

	float m_fovx;
	float m_znear;
	float m_zfar;
	float m_aspectRatio;
	float m_accumPitchDegrees;
	float m_accumHeadDegrees;
	glm::vec3 m_eye;
	glm::vec3 m_xAxis;
	glm::vec3 m_yAxis;
	glm::vec3 m_zAxis;
	glm::vec3 m_viewDir;
	glm::vec3 m_acceleration;
	glm::vec3 m_currentVelocity;
	glm::vec3 m_velocity;
	glm::mat4 m_viewMatrix;
	glm::mat4 m_projMatrix;
	glm::mat4 mProjViewMatrix;

	float m_pitchDegrees;
	float m_headingDegrees;
	float m_rollDegrees;

};

//-----------------------------------------------------------------------------

inline const glm::vec3 &Camera_Alt::getAcceleration() const
{ return m_acceleration; }

inline const glm::vec3 &Camera_Alt::getCurrentVelocity() const
{ return m_currentVelocity; }


inline const glm::mat4 &Camera_Alt::getProjectionMatrix() const
{ return m_projMatrix; }

inline const glm::vec3 &Camera_Alt::getVelocity() const
{ return m_velocity; }

inline const glm::vec3 &Camera_Alt::getViewDirection() const
{ return m_viewDir; }

inline const glm::mat4 &Camera_Alt::getViewMatrix() const
{ return m_viewMatrix; }

inline const glm::vec3 &Camera_Alt::getXAxis() const
{ return m_xAxis; }

inline const glm::vec3 &Camera_Alt::getYAxis() const
{ return m_yAxis; }

inline const glm::vec3 &Camera_Alt::getZAxis() const
{ return m_zAxis; }

inline const float &Camera_Alt::getDistanceFromCamera( glm::vec3 pos ) const {
	return glm::distance( m_eye, pos );
}
inline const float &Camera_Alt::getFov() const {
	return m_fovx;
}
inline const float &Camera_Alt::getZNear() const {
	return m_znear;
}
inline const float &Camera_Alt::getZFar() const {
	return m_zfar;
}